package patinhas.db;

import java.sql.*;

/**
 * Classe que obtém a conexão com o banco de dados,
 * implementando o Design Pattern Singleton.
 *
 * @author pedromoreiralauro
 */
public class DB {

    public static Connection conn;

    /**
     * Método que fornece a instância da conexão com o banco de dados
     *
     * @return
     * @throws java.sql.SQLException
     */
    public static Connection getConn() throws SQLException, Exception {

        if (conn == null) {

            try {
                Class.forName("org.hsqldb.jdbcDriver");

            } catch (Exception e) {

                System.out.println("ERROR: failed to load HSQLDB JDBC driver.");
                throw e;
            }

            conn = DriverManager.getConnection("jdbc:hsqldb:file:db/patinhasDB", "sa", "");


            try {

                /**
                 * Tenta incluir as tabelas necessárias ao sistema,
                 * mesmo sem saber se as mesmas já existem.
                 */
                DB.initTables();

            } catch (SQLException e) {

                /**
                 * Entrará aqui quando der erro, ou seja,
                 * as tabelas já existem e não é necessário
                 * criá-las
                 */
                System.out.println("Banco de Dados já existente.");

            }

        }

        return conn;
    }

    /**
     * Método para finalizar o Banco de dados.
     *
     * @throws java.sql.SQLException
     */
    public static void shutdown() throws SQLException {

        if (conn != null) {
            Statement st = conn.createStatement();

            st.execute("SHUTDOWN");
            conn.close();
        }
    }

    /**
     * Método para incluir todas as tabelas necessárias
     * para o funcionamento do sistema.
     *
     * @throws java.sql.SQLException
     */
    private static void initTables() throws SQLException, Exception {

        StringBuffer sql = new StringBuffer();

        sql.append("CREATE TABLE sample_table ( ");
        sql.append(" id INTEGER IDENTITY, str_col VARCHAR(256) ");
        sql.append(", num_col INTEGER)");

        Statement st = conn.createStatement();

        st.executeUpdate(sql.toString());

        st.close();
    }

    /**
     * Método que realiza os comandos CREATE, DROP, INSERT and UPDATE
     * da linguagem SQL.
     *
     * @param expression
     * @throws java.sql.SQLException
     */
    public static synchronized void update(String expression) throws SQLException, Exception {

        Statement st = DB.getConn().createStatement();

        st.executeUpdate(expression);

        st.close();
    }

    public static void main(String[] args) {

//        try {
//
//            DB.update(
//                    "INSERT INTO sample_table(str_col,num_col) VALUES('Ford', 100)");
//
//            Statement st = null;
//            ResultSet rs = null;
//
//            st = conn.createStatement();
//
//            rs = st.executeQuery("SELECT * FROM sample_table");
//
//            while (rs.next()) {
//
//                System.out.println(rs.getInt("id"));
//            }
//
//            st.close();
//
//            DB.update("drop table sample_table");
//
//            DB.shutdown();
//
//        } catch (Exception ex3) {
//            ex3.printStackTrace();
//        }
    }
}


